package com.representqueens.spark.util;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.representqueens.spark.DataPoint;
import com.representqueens.util.ColorUtils;
import com.representqueens.util.StringUtils;

/**
 * 
 * @author Larry Ogrodnek <larry@cheesesteak.net>
 * @author Rob Whelan <rob@patientsknowbest.com>
 * @version $Revision: 41 $ $Date: 2013-01-08 04:03:56 +0000 (Tue, 08 Jan 2013) $
 */
public final class StringConversion {
    private StringConversion() {
    }

    public static final List<DataPoint> getData(final String data) {
		final String[] pointArr = data.split(",");
	
		final List<DataPoint> out = new ArrayList<DataPoint>(pointArr.length);
	
		boolean foundX = false;
		boolean foundXless = false;
		Double lastX = null;
		for (final String pointSpec : pointArr) {
		    //data=-1.32:x3.32:lo-1.1:hi2.02:shcirc:coblue,
		    DataPoint dp = new DataPoint(pointSpec);
		    if( dp.getX() != null ) {
			foundX = true;
			if( lastX != null && dp.getX() >= lastX )
			    throw new IllegalArgumentException("X values must be ordered; found " + dp.getX() + " after " + lastX );
		    }
		    else {
			foundXless = true;
		    }
		    out.add(dp);
		}
		
		if( foundX && foundXless )
		    throw new IllegalArgumentException("All points must have x values, or none");
	
		if( foundXless ) {
		    // populate default X values -- incremental
		    for(int x=0; x<out.size(); x++) {
			out.get(x).setX(new Double(x));
		    }
		}
		
		return out;
    }

    public static final Color convertColor(final String s, final Color defValue) {
		Color color = null;
	
		if (!StringUtils.isEmpty(s)) {
		    color = ColorUtils.parseColor(s);
		}
	
		return (color == null ? defValue : color);
    }

    public static final int convertInt(final String s, final int defValue) {
		if (!StringUtils.isEmpty(s)) {
		    try {
			return Integer.parseInt(s);
		    } catch (final NumberFormatException nfe) {
			// fall through, return default
		    }
		}
	
		return defValue;
    }
    
    public static final Double convertDouble(final String s, final Double defValue) {
		if (!StringUtils.isEmpty(s)) {
		    try {
			return Double.parseDouble(s);
		    } catch (final NumberFormatException nfe) {
			// fall through, return default
		    }
		}
	
		return defValue;
    }
    
    
    public static List<Double> extractDoubleList(Object data) {
		
		final List<Double> resultList = new ArrayList<Double>();

		if( data == null )
			return resultList;
		
		if (data instanceof List) {
			final List dataList = (List)data;
			for( Object o : dataList ) {
				if (o instanceof Double)
					resultList.add((Double)o);
				else if (o == null)
					resultList.add(null);
				else
					resultList.add(new Double(o.toString()));
			}
			return resultList;
		}
	
		if (data instanceof Double[]) {
			return Arrays.asList((Double[])data);
		}
		
		if (data instanceof Number[]) {
			for (Number n : (Number[])data) {
				if( n == null )
					resultList.add(null);
				else
					resultList.add(new Double(n.toString()));
			}
			return resultList;
		}
	
		if (data instanceof String) {
			return StringUtils.toDoubleList((String)data);
		}
		
		System.err.println("couldn't coerce this data into a List<Double>: " + data);
		return Collections.emptyList();
	}
	
	public static List<Integer> extractIntegerList(Object data) {
		final List<Integer> resultList = new ArrayList<Integer>();
		
		if( data == null )
			return resultList;
		
		if (data instanceof List) {
			final List dataList = (List)data;
			for( Object o : dataList ) {
				if (o instanceof Integer)
					resultList.add((Integer)o);
				else if (o == null)
					resultList.add(null);
				else
					resultList.add(new Integer(o.toString()));
			}
			return resultList;
		}
	
		if (data instanceof Integer[]) {
			return Arrays.asList((Integer[])data);
		}
		
		if (data instanceof Number[]) {
			for (Number n : (Number[])data) {
				if( n == null )
					resultList.add(null);
				else
					resultList.add(new Integer(n.toString()));
			}
			return resultList;
		}
	
		if (data instanceof String) {
			return StringUtils.toIntList((String)data);
		}
		
		System.err.println("couldn't coerce this data into a List<Integer>: " + data);
		return Collections.emptyList();
	}
	
	public static List<String> extractStringList(Object data) {
		final List<String> resultList = new ArrayList<String>();
		
		if( data == null )
			return resultList;
		
		if (data instanceof List) {
			final List dataList = (List)data;
			for( Object o : dataList ) {
				if (o instanceof String)
					resultList.add((String)o);
				else if (o == null)
					resultList.add(null);
				else
					resultList.add(o.toString());
			}
			return resultList;
		}
	
		if (data instanceof String[]) {
			return Arrays.asList((String[])data);
		}
	
		if (data instanceof String) {
			return StringUtils.toStringList((String)data);
		}
		
		System.err.println("couldn't coerce this data into a List<String>: " + data);
		return Collections.emptyList();
	}
}
